package cn.edu.gdu.quizpractice.service.impl;

import cn.edu.gdu.quizpractice.service.OptimizedCounterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Collections;

/**
 * @Author: Aubery
 * @Date: 2025-03-21-23:11
 * @Description:
 */
@Service
public class OptimizedCounterServiceImpl implements OptimizedCounterService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    // Lua 脚本：增加计数并设置过期时间
    private static final String INCREMENT_WITH_EXPIRE_SCRIPT =
            "local current = redis.call('INCR', KEYS[1])\n" +
                    "if current == 1 then\n" +
                    "    redis.call('EXPIRE', KEYS[1], ARGV[1])\n" +
                    "end\n" +
                    "return current";

    // Lua 脚本：减少计数并检查是否删除
    private static final String DECREMENT_SCRIPT =
            "local current = redis.call('DECR', KEYS[1])\n" +
                    "if current <= 0 then\n" +
                    "    redis.call('DEL', KEYS[1])\n" +
                    "end\n" +
                    "return current";

    @Override
    public Long incrementWithExpire(String key, long expireSeconds) {
        return stringRedisTemplate.execute(
                new DefaultRedisScript<>(INCREMENT_WITH_EXPIRE_SCRIPT, Long.class),
                Collections.singletonList(key),
                String.valueOf(expireSeconds)
        );
    }


    /**
     * 减少计数（如果计数为0则删除键）
     *
     * @param key 计数器键
     * @return 减少后的值
     */
    @Override
    public Long decrement(String key) {
        return stringRedisTemplate.execute(
                new DefaultRedisScript<>(DECREMENT_SCRIPT, Long.class),
                Collections.singletonList(key)
        );
    }

    /**
     * 获取当前计数
     *
     * @param key 计数器键
     * @return 当前值
     */
    @Override
    public Long getCount(String key) {
        String value = stringRedisTemplate.opsForValue().get(key);
        return value == null ? 0 : Long.parseLong(value);
    }


    /**
     * 重置计数器
     *
     * @param key 计数器键
     */
    @Override
    public void reset(String key) {
        stringRedisTemplate.delete(key);
    }
}
